import { Injectable, Output, Renderer2, RendererFactory2 } from '@angular/core';
import { Observable, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class DragService {
  dragEl: any;
  timeOut = null;
  private renderer: Renderer2;
  constructor(rendererFactory: RendererFactory2) {
    this.dragEl = document.createElement("div");
    this.renderer = rendererFactory.createRenderer(null, null);
    this.renderer.addClass(this.dragEl, "drag-el");
    this.renderer.setStyle(this.dragEl, "display", "none");
    document.body.appendChild(this.dragEl);
    document.addEventListener("mouseup", event => this.dragEnd(event));
    document.addEventListener("mousemove", event => {
      if (this.isDrag) {
        this.setDragElPos(event);
      }
    })
  }
  sourceType: string;
  sessionId: number;
  fileList: any;
  destElement: any = null;
  isDrag = false;
  destPath = null;
  @Output() onDragDrop = new Subject<any>();
  get onDragDrop$(): Observable<any> { return this.onDragDrop }

  setDragElPos(event: MouseEvent) {
    let width = document.documentElement.clientWidth - this.dragEl.offsetWidth;
    let height = document.documentElement.clientHeight - this.dragEl.offsetHeight;
    let x = event.x - this.dragEl.offsetWidth / 2;
    let y = event.y - this.dragEl.offsetHeight / 2;
    x = Math.min(Math.max(0, x), width);
    y = Math.min(Math.max(0, y), height);
    this.renderer.setStyle(this.dragEl, "left", x + "px");
    this.renderer.setStyle(this.dragEl, "top", y + "px");
  }
  dragStart(event: MouseEvent, sourceType: string, sessionId: number, fileList) {
    this.sourceType = sourceType;
    this.sessionId = sessionId;
    this.fileList = fileList;
    this.isDrag = true;
    let fCount = 0, dCount = 0;
    this.fileList.forEach(file => {
      if (file.type == 'd') dCount++;
      else fCount++;
    });
    let html = "<table><tbody>";
    if (fCount > 0) html += "<tr><td class='counter'>" + fCount + "</td><td>files</td></tr>";
    if (dCount > 0) html += "<tr><td class='counter'>" + dCount + "</td><td>folders</td></tr>";
    html += "</tbody></table>";
    this.dragEl.innerHTML = html;
    this.renderer.setStyle(this.dragEl, "display", 'block');
    this.setDragElPos(event);
  }
  dragEnd(event: MouseEvent) {
    clearTimeout(this.timeOut);
    if (this.isDrag) {
      this.isDrag = false;
      if (this.destElement) this.onDragDrop.next({ listType: this.sourceType, sessionId: this.sessionId, fileList: this.fileList, destPath: this.destPath });
      this.renderer.setStyle(this.dragEl, "display", 'none');
      this.setDragEndObj(null, null);
    }
  }
  setDragEndObj(destType, el = null, destPath = null) {
    if (this.destElement && (el == null || (this.destElement != el && destPath != null))) {
      this.renderer.removeClass(this.destElement, "drag-hover");
      this.destElement = null;
    }
    if (el && this.destElement == null && this.isDrag && this.sourceType != destType) {
      this.renderer.addClass(el, "drag-hover");
      this.destElement = el;
      this.destPath = destPath;
    }
  }
}
